package com.defysoft.waukids.main;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.json.JSONObject;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.view.KeyEvent;

import com.defysoft.waukids.BaseActivity;
import com.defysoft.waukids.BluetoothLeService;
import com.defysoft.waukids.Data_Sharedpreferences;
import com.defysoft.waukids.PublicSharedpreferences;
import com.defysoft.waukids.R;
import com.defysoft.waukids.SampleGattAttributes;
import com.defysoft.waukids.Sqlite_Connect;

public class Main_MainSettting extends BaseActivity {

	private BluetoothAdapter mBluetoothAdapter;
	private static final int REQUEST_ENABLE_BT = 3;
	private long SCAN_PERIOD = 5000;
	private Handler mHandler;
	private Handler mHandlera;
	int stu = 0;
	String beacon = "";
	boolean check = false;
	private BluetoothGattCharacteristic mNotifyCharacteristic;
	private final String LIST_NAME = "NAME";
	private final String LIST_UUID = "UUID";
	private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
	final int SUCCESS = 10;
	final int FAIR = 9;
	final int SCANSUCCESS = 8;
	final int SCANFAIR = 7;
	final int BATTERYUP = 6;
	String battery;
	BluetoothLeService mBluetoothLeService;
	public Sqlite_Connect sqlite_Connect;
	PublicSharedpreferences psf;
	Data_Sharedpreferences.SF_Member member;	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
	    switch (keyCode) {
	    case KeyEvent.KEYCODE_BACK:
	        return true;
	    }
	    return super.onKeyDown(keyCode, event);
	}


	@Override
	protected void onCreate(Bundle arg0) {
		// TODO Auto-generated method stub
		super.onCreate(arg0);
		setContentView(R.layout.prodial);
		sqlite_Connect = new Sqlite_Connect(this);
		psf = new PublicSharedpreferences(this);
		psf.setMembersp();
		member = psf.getMembersp();
		try {
			if (getIntent().getStringExtra("stu_code") != null) {
				stu = Integer.parseInt(getIntent().getStringExtra("stu_code"));
			}
		} catch (Exception e) {
			stu = 0;
		}
		if(stu==0||stu==1){
			finish();
		}
		mHandler = new Handler();
		mHandlera = new Handler();
		mHandlera.postDelayed(new Runnable() {
			@Override
			public void run() {
				
				onNetworkCallback(BATTERYUP, "");
			}
		}, 7000);
		startNetwork(1);


	}

	

	@Override
	public void startThread(int choice) {
		// TODO Auto-generated method stub
		super.startThread(choice);
		final int cho = choice;
		firstThread = new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				switch (cho) {
				case 1:
					mainThread();
					break;
				case 2:
					upThread();
					break;
				}
			}
		});
		firstThread.start();
	}

	@Override
	protected void handlingMessage(Message _message) {
		// TODO Auto-generated method stub
		super.handlingMessage(_message);
		switch (_message.what) {
		case CATCH_EXCEPTION:
			if (firstThread != null) {
				firstThread.interrupt();
			}
			sqlite_Connect.insert_Err_Log((String)_message.obj,android.os.Build.VERSION.SDK_INT,"Main_MainSettting", member.Email);
			finish();
			break;
		case SUCCESS:
			if (firstThread != null) {
				firstThread.interrupt();
			}
			endDIal();
			
					final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
					mBluetoothAdapter = bluetoothManager.getAdapter();
					if (mBluetoothAdapter == null
							|| !mBluetoothAdapter.isEnabled()) {
						finish();
					} else {
					
						check = false;
						scanLeDevice(true);
					}
				
			break;
		case FAIR:
			if (firstThread != null) {
				firstThread.interrupt();
			}
			endDIal();
			finish();
			break;
		case SCANSUCCESS:
			endDIal();
			registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
			final Intent gattServiceIntent = new Intent(this,
					BluetoothLeService.class);
			bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
			
			break;

		case SCANFAIR:

			endDIal();
			finish();
			break;
		case BATTERYUP:
			finish();
			break;
		}

	}

	public void mainThread() {
		try {
			JSONObject jsonObject = new JSONObject(publicHttpCallback(HTTP_URL,
					"code=" + MAIN_JIKIMI + "&stu=" + stu));
			if (jsonObject.getBoolean("success")) {
				beacon = jsonObject.getString("stu");
				onNetworkCallback(SUCCESS, "");
			} else {
				onNetworkCallback(FAIR, jsonObject.getString("message"));
			}
		} catch (Exception e) {
			onNetworkCallback(CATCH_EXCEPTION, e.toString()+" where mainThread()");
		}
	}

	public void upThread() {
		try {
			JSONObject jsonObject = new JSONObject(publicHttpCallback(HTTP_URL,
					"code=" + MAIN_UPBEACON + "&beacon=" + beacon + "&battery="
							+ battery));
			beacon = jsonObject.getString("stu");
			onNetworkCallback(BATTERYUP, "");
		} catch (Exception e) {
			onNetworkCallback(CATCH_EXCEPTION, e.toString()+" where upThread()");
		}
	}

	private void scanLeDevice(final boolean enable) {

		if (enable) {
			// Stops scanning after a pre-defined scan period.
			mHandler.postDelayed(new Runnable() {
				@Override
				public void run() {
					scanLeDevice(false);
					if (!check) {
						endDIal();
						onNetworkCallback(SCANFAIR, "");
					}
				}
			}, SCAN_PERIOD);
			mBluetoothAdapter.startLeScan(mLeScanCallback);
		} else {
			mBluetoothAdapter.stopLeScan(mLeScanCallback);
		}
	}

	private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
		@Override
		public void onLeScan(final BluetoothDevice device, int rssi,
				byte[] scanRecord) {
			final int rss = rssi;
			final byte[] scan = scanRecord;
			runOnUiThread(new Runnable() {
				@Override
				public void run() {
					if (device.getAddress().equals(beacon)) {
						check = true;
						onNetworkCallback(SCANSUCCESS, "");
						scanLeDevice(false);
					}
				}
			});
		}
	};

	private final ServiceConnection mServiceConnection = new ServiceConnection() {

		@Override
		public void onServiceConnected(ComponentName componentName,
				IBinder service) {
			mBluetoothLeService = ((BluetoothLeService.LocalBinder) service)
					.getService();
			if (!mBluetoothLeService.initialize()) {
				finish();
			}
			// Automatically connects to the device upon successful start-up
			// initialization.
			mBluetoothLeService.connect(beacon);

		}

		@Override
		public void onServiceDisconnected(ComponentName componentName) {
			mBluetoothLeService = null;
		}
	};

	private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			final String action = intent.getAction();
			if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
			} else if (BluetoothLeService.ACTION_GATT_DISCONNECTED
					.equals(action)) {
				unregisterReceiver(mGattUpdateReceiver);
			} else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED
					.equals(action)) {
				displayGattServices(mBluetoothLeService
						.getSupportedGattServices());

			} else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
				battery = null;
				battery = intent.getStringExtra(BluetoothLeService.EXTRA_DATA);
				battery=battery.charAt(2)+""+battery.charAt(3);
				battery=getHexToDec(battery);
				unbindService(mServiceConnection);
					mBluetoothLeService.close();
				
				if (battery == null) {
					endDIal();
				} else {
					startNetwork(2);
				}
			}
		}
	};

	private void displayGattServices(List<BluetoothGattService> gattServices) {
		if (gattServices == null)
			return;
		String uuid = null;
		String unknownServiceString = "Unknown service";
		String unknownCharaString = "Unknown characteristic";
		ArrayList<HashMap<String, String>> gattServiceData = new ArrayList<HashMap<String, String>>();
		ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData = new ArrayList<ArrayList<HashMap<String, String>>>();
		mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();

		// Loops through available GATT Services.
		int servicescheck = 0;
		int characteristicscheck = 0;
		int servicescount = 0;
		int characteristicscount = 0;
		for (BluetoothGattService gattService : gattServices) {

			HashMap<String, String> currentServiceData = new HashMap<String, String>();
			uuid = gattService.getUuid().toString();
			currentServiceData.put(LIST_NAME,
					SampleGattAttributes.lookup(uuid, unknownServiceString));
			currentServiceData.put(LIST_UUID, uuid);
			gattServiceData.add(currentServiceData);

			ArrayList<HashMap<String, String>> gattCharacteristicGroupData = new ArrayList<HashMap<String, String>>();
			List<BluetoothGattCharacteristic> gattCharacteristics = gattService
					.getCharacteristics();
			ArrayList<BluetoothGattCharacteristic> charas = new ArrayList<BluetoothGattCharacteristic>();

			// Loops through available Characteristics.
			characteristicscheck = 0;
			for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
				charas.add(gattCharacteristic);
				HashMap<String, String> currentCharaData = new HashMap<String, String>();
				uuid = gattCharacteristic.getUuid().toString();
				currentCharaData.put(LIST_NAME,
						SampleGattAttributes.lookup(uuid, unknownCharaString));
				currentCharaData.put(LIST_UUID, uuid);
				gattCharacteristicGroupData.add(currentCharaData);
				if (uuid.equals("00002a19-0000-1000-8000-00805f9b34fb")) {
					servicescount = servicescheck;
					characteristicscount = characteristicscheck;
				}
				characteristicscheck++;
			}
			mGattCharacteristics.add(charas);
			gattCharacteristicData.add(gattCharacteristicGroupData);
			servicescheck++;
		}

		if (mGattCharacteristics != null) {
			final BluetoothGattCharacteristic characteristic = mGattCharacteristics
					.get(servicescount).get(characteristicscount);
			final int charaProp = characteristic.getProperties();
			if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
				// If there is an active notification on a characteristic, clear
				// it first so it doesn't update the data field on the user
				// interface.
				if (mNotifyCharacteristic != null) {
					mBluetoothLeService.setCharacteristicNotification(
							mNotifyCharacteristic, false);
					mNotifyCharacteristic = null;
				}
				mBluetoothLeService.readCharacteristic(characteristic);
			}
			if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
				mNotifyCharacteristic = characteristic;
				mBluetoothLeService.setCharacteristicNotification(
						characteristic, true);
			}
		}

	}

	private static IntentFilter makeGattUpdateIntentFilter() {
		final IntentFilter intentFilter = new IntentFilter();
		intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
		intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
		intentFilter
				.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
		intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
		return intentFilter;
	}
	
	/**
	  * Hex -> 10진수 변환
	  * @param hex
	  * @return
	  */
	 private String getHexToDec(String hex) {

	   long v = Long.parseLong(hex, 16);   
	   return String.valueOf(v);

	 }
}
